﻿using AutoMapper;
using Inovout.Data.Service;
using Inovout.Descriptor;
using KuaJing.Orders.Domain;
using KuaJing.Organization.Domain;
using KuaJing.People.Domain;
using LinqToExcel;
using System.Collections.Generic;
using System.Linq;

namespace KuaJing.Orders.Service
{
    public class CustomerService : RepositoryService<Customer>
    {
        static CustomerService()
        {
            Mapper.Initialize(cfg => cfg.CreateMap<ICustomer, Customer>());
        }
        private IRepositoryService<Employee> employeeService;
        private IRepositoryService<OrganizationUnit> departmentService;
        public CustomerService(IRepositoryService<Employee> employeeService, IRepositoryService<OrganizationUnit> departmentService)
        {
            this.employeeService = employeeService;
            this.departmentService = departmentService;
        }

        private Employee GetEmployee(string name, string departMentName)
        {
            departMentName = departMentName == "渠道" ? "渠道中心" : "营销中心";
            var employee = employeeService.Query().SingleOrDefault(e => e.Person.Name == name);
            if (employee == null)
            {
                employee = new Employee
                {
                    Person = new Person(name),
                    Status = EmployeeStatus.LeaveJob,
                    Organization = departmentService.Query().Single(d => d.Name == departMentName)
                };
                employeeService.Save(employee);
            }
            return employee;
        }
        public IEnumerable<Customer> Import(string fileName)
        {
            var customers = new List<Customer>();
            using (var excel = new ExcelQueryFactory(fileName))
            {
                var worksheet = excel.Worksheet("客户信息-已报关").ToArray();
                foreach (var row in worksheet)
                {
                    customers.Add(new Customer
                    {
                        ShortName = row[0].ToString(),
                        Province = row[1].ToString(),
                        City = row[2].ToString(),
                        Sales = GetEmployee(row[5].ToString(), row[7].ToString()),
                        Source = GetCustomerSource(row[7].ToString().Trim()),
                        Provider = GetServiceProvider(row[18].ToString().Trim()),
                        Name = row[0].ToString()
                        //Name = row[19].ToString().Trim()
                    });
                }
            }
            var dbCustomers = FindAll().ToArray();
            // BulkInsert(customers.Except(dbCustomers));
            foreach(var insertedCustomer in customers.Except(dbCustomers))
            {
                Save(insertedCustomer);
            }
            foreach (var dbCustomer in dbCustomers.Intersect(customers))
            {
                var customer = customers.Single(c => c.Name == dbCustomer.Name || c.ShortName == dbCustomer.Name);
                if (!StructuralEqualityComparer<ICustomer>.Equals(customer, dbCustomer))
                {
                    Mapper.Map(customer, dbCustomer);
                    customers[customers.IndexOf(customer)] = dbCustomer;
                    Update(dbCustomer);
                }
            }
            return customers;
        }

        private ServiceProvider GetServiceProvider(string provider)
        {
            switch (provider)
            {
                case "江苏跨境":
                    return ServiceProvider.JKJ;
                case "镀互通":
                    return ServiceProvider.MHT;
                default:
                    return ServiceProvider.Unknown;
            }
        }
        private CustomerSource GetCustomerSource(string source)
        {
            switch (source)
            {
                case "直销":
                    return CustomerSource.P2P;
                case "400":
                    return CustomerSource.CallCenter;
                case "在线客服":
                    return CustomerSource.WebSite;
                case "渠道":
                    return CustomerSource.Channel;
                case "直销渠道":
                    return CustomerSource.Introduction;
                default:
                    return CustomerSource.Unknown;
            }
        }

    }
    public static class StructuralEqualityComparer<T>
    {
        public static bool Equals(object x, object y)
        {
            return Equals((T)x, (T)y);
        }
        public static bool Equals(T x, T y)
        {
            return Equals(x, y, TypeDescriptor.Get<T>().Properties);
        }
        public static bool Equals(T x, T y, string[] properties)
        {
            return Equals(x, y, TypeDescriptor.Get<T>().Properties.Where(p => properties.Contains(p.Name)));

        }

        public static bool Equals(T x, T y, IEnumerable<PropertyDescriptor> properties)
        {
            if (x == null || y == null)
            {
                return false;
            }
            foreach (var property in properties)
            {
                if (!EqualityComparer<object>.Default.Equals(property.Getter.Get(x), property.Getter.Get(y)))
                {
                    return false;
                }
            }
            return true;
        }

    }
}
